/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "DXEmitter.h"

namespace directx {

DXEmitter::DXEmitter(void)
:	m_pVertexDeclaration(NULL),
	m_pVertexBuffer(NULL),
	m_iSetParticles(0)
{
}

DXEmitter::~DXEmitter(void)
{
	release();
}

void DXEmitter::reset()
{
	// Create the vertex declaration
	D3DVERTEXELEMENT9 decl[] = {
		{0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},	// Position
		{0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,    0},	// Color
		{0, 28, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE,    0},	// Size
		{0, 32, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},	// Time
		{0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},	// InitPosition
		D3DDECL_END()
	};
	pd3dDevice->CreateVertexDeclaration( decl, &m_pVertexDeclaration);

	// Create the vertex buffer
	pd3dDevice->CreateVertexBuffer(	m_iMaxParticles * sizeof(particlesystem::Particle::sData), 
									D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY | D3DUSAGE_POINTS,  
									0, 
									D3DPOOL_DEFAULT, 
									&m_pVertexBuffer, 
									0);
}

void DXEmitter::release()
{
	RELEASE(m_pVertexBuffer);
	RELEASE(m_pVertexDeclaration);
}

void DXEmitter::updateData()
{
	m_iSetParticles = 0;

	// Copy the particle data to the vertex stream
	m_pVertexBuffer->Lock(0, 0, (void**)&particle, D3DLOCK_DISCARD);
	for (int i=0; i< m_iMaxParticles; ++i) {
		if (m_pParticles[i].getState() == particlesystem::PARTICLE_ALIVE) {
			particle[m_iSetParticles] = m_pParticles[i].m_sData;
			++m_iSetParticles;
		}
	}
	m_pVertexBuffer->Unlock();
	m_bDataUpdate = false;
}

void DXEmitter::drawParticles()
{
	if (m_iSetParticles > 0) {
		// Set the vertex stream and declaration
		pd3dDevice->SetVertexDeclaration( m_pVertexDeclaration );
		pd3dDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(particlesystem::Particle::sData));
		// Draw the particles
		pd3dDevice->DrawPrimitive(D3DPT_POINTLIST, 0, m_iSetParticles);
	}
}

} // namespace
